#include <iostream>

template<typename Derived>
struct Base
{
    void Name() {
        static_cast<Derived*>(this)->impl();
    }
};

struct D1 : public Base<D1>
{
    int d1 = 100;
    void impl() {
        std::cout << d1 << ", " << "D1::impl()" << std::endl;
    }
};

struct D2 : public Base<D2>
{
    int d2 = 100;
    void impl() {
        std::cout  << d2 << ", " << "D2::impl()" << std::endl;
    }
};

template<typename Dervied>
void Func(Base<Dervied> dervied)
{
    dervied.Name();
}

int main () {
    Base<D1> d1;
    Func(d1);

    D1 d1_1;
    Func(d1_1);

    return 0;
}